{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Building prefix dict from the default dictionary ...\n",
      "Loading model from cache d:\\Temp\\jieba.cache\n",
      "Loading model cost 0.244 seconds.\n",
      "Prefix dict has been built successfully.\n"
     ]
    },
    {
     "data": {
      "text/plain": "      word  weight  index_content nature content_type  index_word\n4053    明白     1.0            984     nr          neg          17\n4063    标准     1.0            984      n          neg          27\n4085    免费     1.0            985     vn          neg           2\n4086    免费     1.0            985     vn          neg           3\n4101    免费     1.0            985     vn          neg          18\n...    ...     ...            ...    ...          ...         ...\n9983    免费     1.0           1929     vn          neg           2\n9988     铁     1.0           1932      n          neg           3\n10104   规范     1.0           1951      n          neg          14\n10142    热     1.0           1959      n          neg           1\n10152   免费     1.0           1964     vn          neg           1\n\n[165 rows x 6 columns]",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>word</th>\n      <th>weight</th>\n      <th>index_content</th>\n      <th>nature</th>\n      <th>content_type</th>\n      <th>index_word</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>4053</th>\n      <td>明白</td>\n      <td>1.0</td>\n      <td>984</td>\n      <td>nr</td>\n      <td>neg</td>\n      <td>17</td>\n    </tr>\n    <tr>\n      <th>4063</th>\n      <td>标准</td>\n      <td>1.0</td>\n      <td>984</td>\n      <td>n</td>\n      <td>neg</td>\n      <td>27</td>\n    </tr>\n    <tr>\n      <th>4085</th>\n      <td>免费</td>\n      <td>1.0</td>\n      <td>985</td>\n      <td>vn</td>\n      <td>neg</td>\n      <td>2</td>\n    </tr>\n    <tr>\n      <th>4086</th>\n      <td>免费</td>\n      <td>1.0</td>\n      <td>985</td>\n      <td>vn</td>\n      <td>neg</td>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>4101</th>\n      <td>免费</td>\n      <td>1.0</td>\n      <td>985</td>\n      <td>vn</td>\n      <td>neg</td>\n      <td>18</td>\n    </tr>\n    <tr>\n      <th>...</th>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n    </tr>\n    <tr>\n      <th>9983</th>\n      <td>免费</td>\n      <td>1.0</td>\n      <td>1929</td>\n      <td>vn</td>\n      <td>neg</td>\n      <td>2</td>\n    </tr>\n    <tr>\n      <th>9988</th>\n      <td>铁</td>\n      <td>1.0</td>\n      <td>1932</td>\n      <td>n</td>\n      <td>neg</td>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>10104</th>\n      <td>规范</td>\n      <td>1.0</td>\n      <td>1951</td>\n      <td>n</td>\n      <td>neg</td>\n      <td>14</td>\n    </tr>\n    <tr>\n      <th>10142</th>\n      <td>热</td>\n      <td>1.0</td>\n      <td>1959</td>\n      <td>n</td>\n      <td>neg</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>10152</th>\n      <td>免费</td>\n      <td>1.0</td>\n      <td>1964</td>\n      <td>vn</td>\n      <td>neg</td>\n      <td>1</td>\n    </tr>\n  </tbody>\n</table>\n<p>165 rows × 6 columns</p>\n</div>"
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import re\n",
    "import jieba.posseg as psg\n",
    "\n",
    "# word = pd.read_csv(\"./word.csv\")\n",
    "\n",
    "reviews = pd.read_csv('./reviews.csv')\n",
    "reviews = reviews.drop_duplicates(subset=['content', 'content_type'])\n",
    "content = reviews[\"content\"]\n",
    "# 去除英文、数字、京东、美的、电热水器等词语,pattern\n",
    "strinfo = re.compile('[0-9a-zA-Z]|京东|美的|电热水器|热水器|')\n",
    "content = content.apply(lambda x: strinfo.sub('', x))\n",
    "# 分词\n",
    "worker = lambda s: [(x.word, x.flag) for x in psg.cut(s)]  # 自定义简单分词函数\n",
    "seg_word = content.apply(worker)\n",
    "# 删除停用词\n",
    "stop_path = open(\"./stoplist.txt\", 'r', encoding='UTF-8')\n",
    "stop = stop_path.readlines()\n",
    "stop = [x.replace('\\n', '') for x in stop]\n",
    "# 遍历所有词，取出停用词并选出名词，统计词频\n",
    "word_posneg = pd.DataFrame(columns=['index_content', 'word', 'nature', 'content_type', 'index_word'\n",
    "                                    ])\n",
    "index_content = 0\n",
    "for word_set in seg_word:\n",
    "    index_content += 1\n",
    "    index_word = 0\n",
    "    for w in word_set:\n",
    "        #  index_word += 1\n",
    "        if w[0] not in stop and 'n' in w[1]:\n",
    "            index_word += 1\n",
    "            # DataFrame每行要添加的Series\n",
    "            # word_series = pd.Series(\n",
    "            #     [index_content, w[0], w[1], reviews.iloc[index_content - 1][\"content_type\"], index_word])\n",
    "            # word_posneg = pd.concat([word_posneg, word_series], axis=0, ignore_index=True)\n",
    "            word_posneg.loc[len(word_posneg)] = [index_content, w[0], w[1], reviews.iloc[index_content - 1][\"content_type\"], index_word]\n",
    "\n",
    "# 读入正面、负面情感评价词\n",
    "pos_comment = pd.read_csv(\"./正面评价词语（中文）.txt\", header=None, sep=\"/n\",\n",
    "                          encoding='utf-8', engine='python')\n",
    "neg_comment = pd.read_csv(\"./负面评价词语（中文）.txt\", header=None, sep=\"/n\",\n",
    "                          encoding='utf-8', engine='python')\n",
    "pos_emotion = pd.read_csv(\"./正面情感词语（中文）.txt\", header=None, sep=\"/n\",\n",
    "                          encoding='utf-8', engine='python')\n",
    "neg_emotion = pd.read_csv(\"./负面情感词语（中文）.txt\", header=None, sep=\"/n\",\n",
    "                          encoding='utf-8', engine='python')\n",
    "\n",
    "# 合并情感词与评价词\n",
    "positive = set(pos_comment.iloc[:, 0]) | set(pos_emotion.iloc[:, 0])\n",
    "negative = set(neg_comment.iloc[:, 0]) | set(neg_emotion.iloc[:, 0])\n",
    "\n",
    "# 正负面情感词表中相同的词语\n",
    "intersection = positive & negative\n",
    "\n",
    "positive = list(positive - intersection)\n",
    "negative = list(negative - intersection)\n",
    "\n",
    "positive = pd.DataFrame({\"word\": positive,\n",
    "                         \"weight\": [1] * len(positive)})\n",
    "negative = pd.DataFrame({\"word\": negative,\n",
    "                         \"weight\": [-1] * len(negative)})\n",
    "\n",
    "posneg = pd.concat([positive, negative], ignore_index=True)\n",
    "\n",
    "\n",
    "# 将分词结果与正负面情感词表合并，定位情感词\n",
    "data_posneg = posneg.merge(word_posneg, left_on='word', right_on='word',\n",
    "                           how='right')\n",
    "# data_posneg = data_posneg.sort_values(by = ['index_content','index_word'])\n",
    "\n",
    "data_posneg.head()\n",
    "# 查看原来该句评论问pos，但其中分词后词情感标注未负面的\n",
    "data_posneg[(data_posneg[\"content_type\"]=='pos')&(data_posneg[\"weight\"]<1)]\n",
    "data_posneg[(data_posneg[\"content_type\"]=='neg')&(data_posneg[\"weight\"]==1)]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "  word  weight  index_content nature content_type  index_word\n0   东西     NaN              1     ns          pos           1\n1   品牌     NaN              1      n          pos           2\n2   信赖     1.0              1      n          pos           3\n3   东西     NaN              1     ns          pos           4\n4   整体     NaN              1      n          pos           5",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>word</th>\n      <th>weight</th>\n      <th>index_content</th>\n      <th>nature</th>\n      <th>content_type</th>\n      <th>index_word</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>东西</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>ns</td>\n      <td>pos</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>品牌</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>n</td>\n      <td>pos</td>\n      <td>2</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>信赖</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>n</td>\n      <td>pos</td>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>东西</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>ns</td>\n      <td>pos</td>\n      <td>4</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>整体</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>n</td>\n      <td>pos</td>\n      <td>5</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_posneg.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "module 'pandas' has no attribute 'arange'",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mAttributeError\u001B[0m                            Traceback (most recent call last)",
      "\u001B[1;32md:\\Temp\\ipykernel_13376\\2645861326.py\u001B[0m in \u001B[0;36m<module>\u001B[1;34m\u001B[0m\n\u001B[0;32m      9\u001B[0m \u001B[1;31m# 构造新列，作为经过否定词修正后的情感值\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m     10\u001B[0m \u001B[0mdata_posneg\u001B[0m\u001B[1;33m[\u001B[0m\u001B[1;34m'amend_weight'\u001B[0m\u001B[1;33m]\u001B[0m \u001B[1;33m=\u001B[0m \u001B[0mdata_posneg\u001B[0m\u001B[1;33m[\u001B[0m\u001B[1;34m'weight'\u001B[0m\u001B[1;33m]\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[1;32m---> 11\u001B[1;33m \u001B[0mdata_posneg\u001B[0m\u001B[1;33m[\u001B[0m\u001B[1;34m'id'\u001B[0m\u001B[1;33m]\u001B[0m \u001B[1;33m=\u001B[0m \u001B[0mnp\u001B[0m\u001B[1;33m.\u001B[0m\u001B[0marange\u001B[0m\u001B[1;33m(\u001B[0m\u001B[1;36m0\u001B[0m\u001B[1;33m,\u001B[0m \u001B[0mlen\u001B[0m\u001B[1;33m(\u001B[0m\u001B[0mdata_posneg\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0m\u001B[0;32m     12\u001B[0m \u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m     13\u001B[0m \u001B[1;31m# 只保留有情感值的词语\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n",
      "\u001B[1;32m~\\anaconda3\\lib\\site-packages\\pandas\\__init__.py\u001B[0m in \u001B[0;36m__getattr__\u001B[1;34m(name)\u001B[0m\n\u001B[0;32m    259\u001B[0m         \u001B[1;32mreturn\u001B[0m \u001B[0m_SparseArray\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m    260\u001B[0m \u001B[1;33m\u001B[0m\u001B[0m\n\u001B[1;32m--> 261\u001B[1;33m     \u001B[1;32mraise\u001B[0m \u001B[0mAttributeError\u001B[0m\u001B[1;33m(\u001B[0m\u001B[1;34mf\"module 'pandas' has no attribute '{name}'\"\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0m\u001B[0;32m    262\u001B[0m \u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m    263\u001B[0m \u001B[1;33m\u001B[0m\u001B[0m\n",
      "\u001B[1;31mAttributeError\u001B[0m: module 'pandas' has no attribute 'arange'"
     ]
    }
   ],
   "source": [
    "\n",
    "ath = \"./\"  # assuming the not.csv file is in the same directory as this script\n",
    "\n",
    "data_posneg = pd.read_csv(\"./data_posneg.csv\")\n",
    "# 载入否定词表\n",
    "notdict = pd.read_csv(path+\"/not.csv\")\n",
    "\n",
    "# 构造新列，作为经过否定词修正后的情感值\n",
    "data_posneg['amend_weight'] = data_posneg['weight']\n",
    "data_posneg['id'] = np.arange(0, len(data_posneg))\n",
    "\n",
    "# 只保留有情感值的词语\n",
    "only_inclination = data_posneg.dropna().reset_index(drop=True)\n",
    "\n",
    "index = only_inclination['id']\n",
    "\n",
    "\n",
    "for i in np.arange(0, len(only_inclination)):\n",
    "    # 提取第i个情感词所在的评论\n",
    "    review = data_posneg[data_posneg['index_content'] == only_inclination['index_content'][i]]\n",
    "    review.index = np.arange(0, len(review))\n",
    "    # 第i个情感值在该文档的位置\n",
    "    affective = only_inclination['index_word'][i]\n",
    "    if affective == 1:\n",
    "        ne = sum([i in notdict['term'] for i in review['word'][affective - 1]])%2\n",
    "        if ne == 1:\n",
    "            data_posneg['amend_weight'][index[i]] = -data_posneg['weight'][index[i]]          \n",
    "    elif affective > 1:\n",
    "        ne = sum([i in notdict['term'] for i in review['word'][[affective - 1, \n",
    "                  affective - 2]]])%2\n",
    "        if ne == 1:\n",
    "            data_posneg['amend_weight'][index[i]] = -data_posneg['weight'][index[i]]\n",
    "            \n",
    "\n",
    "            \n",
    "# 更新只保留情感值的数据\n",
    "only_inclination = only_inclination.dropna()\n",
    "\n",
    "# 计算每条评论的情感值\n",
    "emotional_value = only_inclination.groupby(['index_content'],\n",
    "                                           as_index=False)['amend_weight'].sum()\n",
    "\n",
    "# 去除情感值为0的评论\n",
    "emotional_value = emotional_value[emotional_value['amend_weight'] != 0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.13"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
